closely match that of other devices.
This involves moving the logic for backend creation out of the image
handlers and in to the device handler, which is a much more sensible
place for it.
Signed-off-by: Steven Smith <sos22@cam.ac.uk>
try:
self._constructDomain()
self._storeVmDetails()
- self._restoreDomain()
+ self._createDevices()
self._createChannels()
self._storeDomDetails()
self._endRestore()
raise VmError(str(exn))
- def _restoreDomain(self):
- log.debug('XendDomainInfo.restoreDomain: %s %s',
- self.domid,
- self.info['cpu_weight'])
-
- if not self.infoIsSet('image'):
- raise VmError('Missing image in configuration')
-
- try:
- self.image = image.create(self,
- self.info['image'],
- self.info['device'])
-
- self._createDevices()
- except RuntimeError, exn:
- raise VmError(str(exn))
-
def cleanupDomain(self):
"""Cleanup domain resources; release devices. Idempotent. Nothrow
guarantee."""
import signal
import xen.lowlevel.xc
-import xen.util.auxbin
from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
from xen.xend.XendError import VmError, XendError
from xen.xend.XendLogging import log
ramdisk = self.ramdisk,
features = self.vm.getFeatures())
- def configure(self, imageConfig, deviceConfig):
- ImageHandler.configure(self, imageConfig, deviceConfig)
-
- self.pid = 0
- log.info("configuring linux guest")
-
- # set up the graphics bits.
- # FIXME: this is much like what we do for HVM, should it be
- # for all image types now?
- self.display = sxp.child_value(imageConfig, 'display')
- self.xauthority = sxp.child_value(imageConfig, 'xauthority')
- self.vncconsole = sxp.child_value(imageConfig, 'vncconsole')
- vncpasswd = sxp.child_value(imageConfig, 'vncpasswd')
- self.vncpasswd = vncpasswd
-
- self.vnc = sxp.child_value(imageConfig, 'vnc')
- self.sdl = sxp.child_value(imageConfig, 'sdl')
- if self.vnc:
- self.vncdisplay = int(sxp.child_value(imageConfig, 'vncdisplay',
- self.vm.getDomid()))
- self.vncunused = sxp.child_value(imageConfig, 'vncunused')
- self.vnclisten = sxp.child_value(imageConfig, 'vnclisten')
- if not(self.vnclisten):
- self.vnclisten = xen.xend.XendRoot.instance().get_vnclisten_address()
-
- def createDeviceModel(self):
- if self.pid:
- return
- # Execute device model (for us, it's just the fb frontend)
- if not self.vnc and not self.sdl:
- return
-
- if self.vnc:
- args = [xen.util.auxbin.pathTo("xen-vncfb")]
- if self.vncunused:
- args += ['--unused']
- elif self.vncdisplay:
- args += [ "--vncport", "%d" %(5900 + self.vncdisplay,) ]
- if self.vnclisten:
- args += [ "--listen", self.vnclisten ]
-
- # password check
- if self.vncpasswd is None:
- # get password from xend-config(if password omitted, None)
- self.vncpasswd = xen.xend.XendRoot.instance().get_vncpasswd_default()
-
- if self.vncpasswd is None:
- raise VmError('vncpasswd is not setup in the guest config or xend-config.')
- if self.vncpasswd != '':
- self.vm.storeVm("vncpasswd", self.vncpasswd)
- log.info("vncpassword set to '%s'", self.vncpasswd)
-
- elif self.sdl:
- args = [xen.util.auxbin.pathTo("xen-sdlfb")]
- args = args + [ "--domid", "%d" % self.vm.getDomid(),
- "--title", self.vm.info['name'] ]
-
- env = dict(os.environ)
- if self.display:
- env['DISPLAY'] = self.display
- if self.xauthority:
- env['XAUTHORITY'] = self.xauthority
- log.info("spawning video: %s", args)
- self.pid = os.spawnve(os.P_NOWAIT, args[0], args, env)
- log.info("device model pid: %d", self.pid)
-
def destroy(self):
if not self.pid:
return
from xen.xend.server.DevController import DevController
+from xen.xend.XendError import VmError
+import xen.xend
+import os
+
class VfbifController(DevController):
"""Virtual frame buffer controller. Handles all vfb devices for a domain.
"""
front = {}
return (devid, back, front)
+ def createDevice(self, config):
+ DevController.createDevice(self, config)
+ std_args = [ "--domid", "%d" % self.vm.getDomid(),
+ "--title", self.vm.getName() ]
+ t = config.get("type", None)
+ if t == "vnc":
+ # Try to start the vnc backend
+ args = [xen.util.auxbin.pathTo("xen-vncfb")]
+ if config.has_key("vncunused"):
+ args += ["--unused"]
+ elif config.has_key("vncdisplay"):
+ args += ["--vncport", "%d" % (5900 + config["vncdisplay"])]
+ vnclisten = config.get("vnclisten",
+ xen.xend.XendRoot.instance().get_vnclisten_address())
+ args += [ "--listen", vnclisten ]
+ os.spawnve(os.P_NOWAIT, args[0], args + std_args, os.environ)
+ elif t == "sdl":
+ args = [xen.util.auxbin.pathTo("xen-sdlfb")]
+ env = dict(os.environ)
+ if config.has_key("display"):
+ env['DISPLAY'] = config["display"]
+ if config.has_key("xauthority"):
+ env['XAUTHORITY'] = config["xauthority"]
+ os.spawnve(os.P_NOWAIT, args[0], args + std_args, env)
+ else:
+ raise VmError('Unknown vfb type %s (%s)' % (t, repr(config)))
+
class VkbdifController(DevController):
"""Virtual keyboard controller. Handles all vkbd devices for a domain.
"""
- def __init__(self, vm):
- DevController.__init__(self, vm)
-
def getDeviceDetails(self, config):
"""@see DevController.getDeviceDetails"""
devid = 0
use="""Add a physical USB port to a domain, as specified by the path
to that port. This option may be repeated to add more than one port.""")
-gopts.var('vfb', val="no|yes'",
- fn=set_bool, default=0,
- use="Make the domain a framebuffer backend.")
-
-gopts.var('vkbd', val="no|yes'",
- fn=set_bool, default=0,
- use="Make the domain a keyboard backend.")
+gopts.var('vfb', val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY",
+ fn=append_value, default=[],
+ use="""Make the domain a framebuffer backend.
+ The backend type should be either sdl or vnc.
+ For type=vnc, connect an external vncviewer. The server will listen
+ on ADDR (default 127.0.0.1) on port N+5900. N defaults to the
+ domain id. If vncunused=1, the server will try to find an arbitrary
+ unused port above 5900.
+ For type=sdl, a viewer will be started automatically using the
+ given DISPLAY and XAUTHORITY, which default to the current user's
+ ones.""")
gopts.var('vif', val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT,backend=DOM,vifname=NAME",
fn=append_value, default=[],
if vals.builder == 'hvm':
configure_hvm(config_image, vals)
-
- configure_graphics(config_image, vals)
return config_image
config_devs.append(['device', config_usb])
def configure_vfbs(config_devs, vals):
- if vals.vfb:
- config_devs.append(['device', ['vfb', []]])
-
-def configure_vkbds(config_devs, vals):
- if vals.vkbd:
- config_devs.append(['device', ['vkbd', []]])
+ for f in vals.vfb:
+ d = comma_sep_kv_to_dict(f)
+ config = ['vfb']
+ if not d.has_key("type"):
+ d['type'] = 'sdl'
+ for (k,v) in d.iteritems():
+ if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display',
+ 'xauthority', 'type' ]:
+ err("configuration option %s unknown to vfbs" % k)
+ config.append([k,v])
+ if not d.has_key("display") and os.environ.has_key("DISPLAY"):
+ config.append(["display", os.environ['DISPLAY']])
+ if not d.has_key("xauthority"):
+ config.append(["xauthority", get_xauthority()])
+ config_devs.append(['device', ['vkbd']])
+ config_devs.append(['device', config])
def configure_security(config, vals):
"""Create the config for ACM security labels.
config_devs.append(['device', config_vif])
-def configure_graphics(config_image, vals):
- """Create the config for graphic consoles.
- """
- args = [ 'vnc', 'vncdisplay', 'vncconsole', 'vncunused',
- 'sdl', 'display', 'xauthority', 'vnclisten', 'vncpasswd']
- for a in args:
- if (vals.__dict__[a]):
- config_image.append([a, vals.__dict__[a]])
-
def configure_hvm(config_image, vals):
"""Create the config for HVM devices.
"""
args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb',
'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
+ 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
+ 'sdl', 'display', 'xauthority',
'acpi', 'apic', 'usb', 'usbdevice', 'keymap' ]
for a in args:
if a in vals.__dict__ and vals.__dict__[a] is not None:
configure_usb(config_devs, vals)
configure_vtpm(config_devs, vals)
configure_vfbs(config_devs, vals)
- configure_vkbds(config_devs, vals)
configure_security(config, vals)
config += config_devs